package com.atguigu.springcloud.core;

import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;

import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.Callable;

/**
 * @author xiaolong
 * @version 1.0
 * @description: Hystrix传播ThreadLocal对象
 * 编写自定义并发策略比较简单，只需编写一个类，让其继承HystrixConcurrencyStrategy ，
 * 并重写wrapCallable 方法即可。会生成callable线程对象
 * @date 2021/10/14 11:38
 */
public class GosunHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {


    private final Collection<HystrixCallableWrapper> wrappers;


    public GosunHystrixConcurrencyStrategy(Collection<HystrixCallableWrapper> wrappers) {
        this.wrappers = wrappers;
    }


    //将产生的callable对象传入方法中去
    @Override
    public <T> Callable<T> wrapCallable(Callable<T> callable) {
        return new CallableWrapperChain<>(callable, wrappers.iterator()).wrapCallable();
    }


    //我们将要传播的对象作为成员变量，并在其中的call方法中，为静态方法设值。
    private static class CallableWrapperChain<T> {

        private final Callable<T> callable;

        //集合的一个迭代器
        private final Iterator<HystrixCallableWrapper> wrappers;

        public CallableWrapperChain(Callable<T> callable, Iterator<HystrixCallableWrapper> wrappers) {
            this.callable = callable;
            this.wrappers = wrappers;
        }

        //将产生的callable对象传入方法中去
        Callable<T> wrapCallable() {
            Callable<T> delegate = callable;
            while (wrappers.hasNext()) {
                delegate = wrappers.next().wrap(delegate);
            }
            return delegate;
        }

    }

}
